package cn.tedu.charging.cost.service.impl;

import cn.tedu.charging.common.pojo.param.ProgressCostParam;
import cn.tedu.charging.common.pojo.po.ChargingCostRulePO;
import cn.tedu.charging.common.pojo.vo.ProgressCostVO;
import cn.tedu.charging.cost.repository.CostRepository;
import cn.tedu.charging.cost.service.CostService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;

@Service
public class CostServiceImpl implements CostService {
    @Resource
    private CostRepository costRepository;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    public ProgressCostVO calculateCost(ProgressCostParam cost) {
        /* 1. 利用参数中 stationId 和gunId 获取枪类型 计算当前系统时间所属的时间段
            上午尖 [8~12)点 下午尖 [14~18)
            峰 [18~24)
            平 [12~14)
            谷 [0~8)
            select * from charging_cost_rule where station_id=5 and start_time<=now()
            and end_time>now() */
        cost.setStationId(5);
        ChargingCostRulePO ccp = costRepository.getCostRule(cost);
        // 2.入参电度数 规则单价 计算本次金额
        BigDecimal onceFee = calculateOnceFee(cost.getChargingCapacity(),ccp.getPowerFee());
        // 3.时间和金额累加
        Long totalTime = accumulateTime(5L,cost.getOrderNo());// 默认一次充电时间20秒
        BigDecimal totalFee = accumulateFee(onceFee,cost.getOrderNo());
        ProgressCostVO vo = new ProgressCostVO();
        vo.setTotalCost(totalFee.doubleValue());
        vo.setPowerFee(ccp.getPowerFee().doubleValue());
        vo.setTotalTime(totalTime);
        return vo;
    }

    private BigDecimal accumulateFee(BigDecimal onceFee, String orderNo) {
        String feeKey = "charging:bill:fee:" + orderNo;
        // 金额是浮点型,redisTemplate自动识别 转化了浮点型和整形过程
        Double increment = redisTemplate.opsForValue().increment(feeKey, onceFee.doubleValue());
        return new BigDecimal(increment).setScale(2, RoundingMode.HALF_UP);
    }

    private Long accumulateTime(long l, String orderNo) {
        String timeKey = "charging:bill:time:" + orderNo;
        return redisTemplate.opsForValue().increment(timeKey, l);
    }

    private BigDecimal calculateOnceFee(Double chargingCapacity, BigDecimal powerFee) {
        /* 充电度数capacity*单价powerFee
        BigDecimal + plus - minus - multiply / devided
        精度2为 四舍五入 */
        return powerFee.multiply(new BigDecimal(chargingCapacity)).setScale(2, RoundingMode.HALF_UP);
    }
}
